package com.jinke.api.common.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.jinke.api.modules.app.model.FindZoneResult;
import com.jinke.api.modules.app.service.FindZoneResultService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.compress.utils.Lists;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Component;

import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Component
@RequiredArgsConstructor
public class FedexRateTool {

    private final FindZoneResultService findZoneResultService;


    /**
     * 获取区
     * @param from
     * @param to
     * @return
     */
    public List<String>  getZone(String from,String to,int tryTime) {
        List<String> zoneList;
        List<FindZoneResult> allrealdyHasResultList = findZoneResultService.findInfoBy2Zipcode(from, to);
        if (CollectionUtil.isNotEmpty(allrealdyHasResultList)) {
            zoneList=Lists.newArrayList();
            //防止对其他影响 只取最后一条
            FindZoneResult findZoneResult = allrealdyHasResultList.get(0);
            zoneList.add(findZoneResult.getExpressZone().toString());
            zoneList.add(findZoneResult.getGroundZone().toString());
            return  zoneList;
        }else {
            zoneList = okhttp(from, to, tryTime);
            if (zoneList != null ) {
                //查不是是有待更新的
                List<FindZoneResult> mayToUpDateList = findZoneResultService.countBy2ZipCode(from, to);
                if (CollectionUtil.isEmpty(mayToUpDateList)){
                    //加一条有结果的
                    addOneZoneResult(from, to, zoneList);
                }else {
                    //更新
                    for (FindZoneResult findZoneResult : mayToUpDateList) {
                        findZoneResult.setGroundZone(Integer.valueOf(zoneList.get(0)));
                        findZoneResult.setExpressZone(Integer.valueOf(zoneList.get(1)));
                    }
                    findZoneResultService.updateBatchById(mayToUpDateList);
                }

                return zoneList;
            }else {
                //出错了
                List<FindZoneResult> mayToUpDateList = findZoneResultService.countBy2ZipCode(from, to);
                if (CollectionUtil.isEmpty(mayToUpDateList)){
                    // 不存在 插入 数据库
                    addOneZoneResult(from, to, null);
                }
            }

        }
        return null;
    }

    private void addOneZoneResult(String from, String to, List<String> zoneList) {
        // 不存在 插入 数据库
        FindZoneResult findZoneResult = new FindZoneResult();
        findZoneResult.setFromZipCode(from);
        findZoneResult.setToZipCode(to);
        // 请求默认us 这里也默认us
        findZoneResult.setCountry("us");
        if (zoneList!=null){
            findZoneResult.setGroundZone(Integer.valueOf(zoneList.get(0)));
            findZoneResult.setExpressZone(Integer.valueOf(zoneList.get(1)));
        }
        findZoneResultService.save(findZoneResult);
    }

    private static List<String> okhttp(String from, String to, int tryTime) {
        if (tryTime == 0) {
            return null;
        }
        try {
            OkHttpClient client = new OkHttpClient().newBuilder()
                    .build();
            MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
            ;
            RequestBody body = RequestBody.create(mediaType, "method=FindZones&origPostalCd=" + from + "&destCountryCd=us&destPostalCd=" + to);
            Request request = new Request.Builder()
                    .url("https://www.fedex.com/ratetools/RateToolsMain.do")
                    .method("POST", body)
                    .addHeader("authority", "www.fedex.com")
                    .addHeader("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7")
                    .addHeader("accept-language", "zh-CN,zh;q=0.9")
                    .addHeader("cache-control", "max-age=0")
                    .addHeader("origin", "https://www.fedex.com")
                    .addHeader("referer", "https://www.fedex.com/ratetools/RateToolsMain.do?method=FindZones&origPostalCd=92337&destCountryCd=us&destPostalCd=71746")
                    .addHeader("sec-ch-ua", "\"Chromium\";v=\"122\", \"Not(A:Brand\";v=\"24\", \"Google Chrome\";v=\"122\"")
                    .addHeader("sec-ch-ua-mobile", "?0")
                    .addHeader("sec-ch-ua-platform", "\"Windows\"")
                    .addHeader("sec-fetch-dest", "document")
                    .addHeader("sec-fetch-mode", "navigate")
                    .addHeader("sec-fetch-site", "same-origin")
                    .addHeader("sec-fetch-user", "?1")
                    .addHeader("upgrade-insecure-requests", "1")
                    .addHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36")
                    .addHeader("Cookie", "_ga=GA1.1.1033527143.1720149998; _ga_EBFDJH3RN3=GS1.1.1720149998.1.1.1720150019.39.0.0; fdx_cbid=31211212281720150020226690383031; fdx_redirect=en-us; cc_path=us; gdl-clientId=c0f26e90-e878-4562-9e54-6b1a4b7cba21; s_ecid=MCMID%7C10784205287372228014275659697186311541; _sfid_9c70={%22anonymousId%22:%2239c97f248970ce2e%22%2C%22consents%22:[]}; _cls_v=507b882e-bb9d-43dd-81b0-c31e74bb4cc6; _evga_92b6={%22uuid%22:%2239c97f248970ce2e%22%2C%22puid%22:%22DYvHWRLACmZ3unD9FmZ7vES8z7ZSA6T4LLS08ZTN46GF4r06Cv3P2r8vSdvY0oo_bf4teXgdmEwNAuM76Iq2enI669H_Z4AY_2G8XEr5EDc%22%2C%22affinityId%22:%2204p%22}; coveo_visitorId=8fb98ad2-3998-4996-ac04-0050349d3303; optimizelyEndUserId=oeu1720158826111r0.7181694759283348; _svtri=4d00d9c4-6220-478f-b3b0-7ce62bd22171; gdl_r42_store_mappings_p={%222001%22:%22FE5SK7bdrp%22}; _svs=%7B%22p%22%3A%7B%2243%22%3A1720158831616%2C%222001%22%3A1720158831612%7D%7D; _scid=ae46668f-c75d-472b-b7b7-76d437834eaa; _scid_r=ae46668f-c75d-472b-b7b7-76d437834eaa; _tt_enable_cookie=1; _ttp=dkDQT2T9DoOGqZE04IKdKNpExVV; _rdt_uuid=1720158833026.731c0550-c94e-4c5f-b84f-08d82a8ce19d; _gcl_au=1.1.1433377454.1720150023.601494486.1720158922.1720160539; sc_fcl_uuid=FE5SK7bdrp; s_fid=17D45B2CAAD0534B-0E6F3453E72E34B3; mbox=PC#0171b31af8d34a95987d71b4ee554c7b.38_0#1784351405|session#6e933266ffae43b0be77a0744a14da03#1721108465; fdx_locale=en_US; AMCVS_1E22171B520E93BF0A490D44%40AdobeOrg=1; AMCV_1E22171B520E93BF0A490D44%40AdobeOrg=179643557%7CMCIDTS%7C19935%7CMCMID%7C10784205287372228014275659697186311541%7CMCAAMLH-1722997837%7C11%7CMCAAMB-1722997837%7CRKhpRz8krg2tLO6pguXWp5olkAcUniQYPHaMWWgdJ3xzPWQmdj0y%7CMCOPTOUT-1722400237s%7CNONE%7CMCAID%7CNONE%7CvVersion%7C5.5.0; s_pers=%20sc_fcl_uuid%3DFE5SK7bdrp%7C1727934875994%3B%20s_dfa%3Dfedexglbl%7C1722394837854%3B%20gpv_pageName%3Dfedex%252Flocal%252Fen-us%7C1722394838857%3B%20s_vnum%3D1722441600867%2526vn%253D1%7C1722441600867%3B%20s_invisit%3Dtrue%7C1722394838867%3B; s_cc=true; s_sess=%20SC_LINKS%3D%3B%20s_ppv%3Dfedex%252Flocal%252Fen-us%252C21%252C20%252C968%3B; siteDC=edc; xacc=NL; OTHERRATETOOLSSESSIONID=DrUq-ybIWppIMYbKRyYaTQ2upNF8GS623jirZwn56KFzvAeHTpBE!-1901079694; Rbt=f0; fdx_bman=a271eac42228122b06631f44bd5d3a9e; PIM-SESSION-ID=di3tknlYVI3YMMEV; _abck=33CDD2516E77AF7D6256433BDDB72C4E~0~YAAQPvBuaChDkyeRAQAAYCz7KgwP3zA+HGbrdruSiEjyYGrYMrm2Vcf4TwzmMOElVtx/t2DIW5mLAKEWILiLzd+KLcmSyaATmOwWMic1ndwmoYfczc6SYjwrQ7/uvLVJMTf3y7PVAO/p5xQLiwF/GdXD9k8/8ACiO4tyjFWLgAu/0f5wUQneo+W+h9UNUTXzy++S67u0DqeSOIWLc3g6qdZmfn8hwMCq/fYl8W5XQPZhqe8jKTRRNNOwpqkRcx17ZXYruRLDGzzXsKR4iSRm9kakhL3Hd/y1mZSLeea/K5XRrF+4qxtIQSpx8XsQc1Gp3r2Z264ICPLSb8yx/VY48YVqrsEVqVZUfk9I4aaqmsgYwI4/hfUDjx7/xNkQJmh9dLs95nqZ/B9yWV+QNLR6u4zWOY+OZBrlMC3CaHilz/myPK8isdZhQLT8AfApPdmOhdgjJr1uq/vNRcFoRNaf24/V/w; bm_mi=E63EB3E9007D299E0043720DC49D1EDF~YAAQN/BuaJsQdQKRAQAAmz0QKxhbHxC8b8QAs2SbYU1XzuvVTK2tInS/4Zg13HoAg5CCPypCGuOOHijwY7mqdjTNup0/lVzu/beNefTys8Seku3mcbtDwJngA8eOx/xIw8hUyAUX9z63V1SXfOhuPnh+K4NTiR+dL8mUicUH6kLnEWZUkq3nwJw4kfQzwp9WG757QoWKdsU2KYSUwhyxZExiAnyerENS/cHhbEDnKREJYhfAJcqD6rnaswwjZ+JqV5FoIecZh0pnAfV+5VfLYsL7gYKBY034tKn95Ujs1EBMBex7woWi/6CwJ63DSOA+IwpzivAVMD9DV91Jlr0vbJYbqYfyQB0; bm_sv=7A26A208B7A6344C7326A3D657D98CD5~YAAQN/BuaJwQdQKRAQAAmz0QKxiyU0ieN6O6tFhhpZtn7NTGvJ/9aPpw3B3/5cCR293yPYtqgAtjxoqVpRDDMg1AwKa2D3dipPQEaZ+svYzPXKtGVXx5i3XI5bdNFYGgLGVcx+BqQDPgPLAX68b9doxtPBPUGsnWuqVs+2lVQNllLeAQEQu3RC3v0UKqc+JRhmwL6BlbjkRko5nBLzO06EBcAYByPD41LN6K9PFA/Xwv/Hclsb0cU9KTczUHztI; bm_sz=2C17F0D20BADFF71D45DBFC79EB75B08~YAAQN/BuaJ0QdQKRAQAAmz0QKxj/6l+/MmuXmQ0H9OeNDeMFcJgSKmStesEb7PfFt19+AqfJQh7r9Np2ljelKfOR5GAHLZ6VfsMiV4kPYkQwBZxWhzlKIV4XP+4Wqdohg9m3BWAoB00noYUYK0B/kRgZAUbQbjyiMRdqKNTKkT/MPspcZlZCDG0iEPJhOBg0K+BqVP4bN+LdCty7cDpTiy7ZYUjDmByP/isYKjNMfOGR6AoGnNW5co06r4qy2/FgzMgPvbCHjr997ZAm7x6cwIb+61FAmgZuk+kDg9gNrncsMlqtY61hCB8wBXgDSUNItw4pzFWGb3Hhvv5DhDQurNRoEInPxmEDAh9OgaI4bbOUNYYVZK65hwqPQXIAgeJ/tIWTiPX7FrmxK8PgVYfsZ9ObhNgoG4o; ak_bmsc=518ABA5826321E7B2CD998592F8E8ACB~000000000000000000000000000000~YAAQN/BuaNAQdQKRAQAA7kQQKxgb1II7UyJF/BAY7QxB0uGhMMqlRL7rPowZqwB21DLGlDD8FinfKNjPvVWW4twwvvvGZjXqTozUeFiSv24oFp+qe4T5o/CLnkFGOHSrSVf+4xIpq6TaD0+2xBYqY//zto4k1ZRsq221cChfcWlXoRFJpsI8OS5pHYiY7jJPCFohMTquXKcF+JBkxlaQ85LmqlLizc8cz5x76fTG5o29okgB1sTBbQOGpI2ruqYeG6vHCN7r+A2EluPqr0hy5786jiPh2ZzZG+Nq3jcrs8glZT7m+rdumsvX1RRyhkVEPOcgYFLSeHdm9WhlkQP8ho46AYTlf+R1FjIMx7yV12OVzCyDlrqm8qdDew1Jq3+nXboG1B4uH/GrKQw+fvqOw2alFzICW1K4QF0uyh6MJ7m5awiOtk9ghlckrtBDZ4b98BzOP8DAgtdc1yJwW7cuCI3yqTuTXT5+3uAt0Sde9O4fyoaRDFSADJlCmUIjZ0adVYgJrxF9QQ")
                    .addHeader("content-type", "application/x-www-form-urlencoded")
                    .build();

            Response response = client.newCall(request).execute();
            String responseBody = response.body().string();
            List<String> print = print(responseBody);
            //偏远地区查不到
            if (print.get(0).equals("*")||print.get(1).equals("NA")){
                print.set(0,"0");
                print.set(1,"0");
                log.error("偷区偏远地区{}, from:{}, to:{}",  from, to);
            }
            return print;
        } catch (Exception e) {
            tryTime--;
            log.error("偷区出错还剩下重试次数{}, from:{}, to:{}, err:{}", tryTime, from, to, e.getMessage());
            return okhttp(from, to, tryTime);
        }

    }

    private static String followRedirect(String url) {
        try {
            HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
            con.setInstanceFollowRedirects(false);
            con.setRequestMethod("GET");

            int responseCode = con.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_MOVED_PERM || responseCode == HttpURLConnection.HTTP_MOVED_TEMP||responseCode==308) {
                String newUrl = con.getHeaderField("Location");
                return newUrl;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static List<String> print(String htmlContent) {

        // Parse the HTML content
        Document doc = Jsoup.parse(htmlContent);

        // Select all script elements
        Elements scriptElements = doc.select("script");

        // Variables to store the extracted values
        String expressZone = null;
        String groundZone = null;

        // Iterate through each script element
        for (Element scriptElement : scriptElements) {
            String scriptContent = scriptElement.html();

            // Check if the script content contains the variables we are looking for
            if (scriptContent.contains("var expressZone") && scriptContent.contains("var groundZone")) {
                // Extract expressZone value
                int expressZoneStart = scriptContent.indexOf("var expressZone") + "var expressZone".length() + 3;
                int expressZoneEnd = scriptContent.indexOf(";", expressZoneStart);
                expressZone = scriptContent.substring(expressZoneStart, expressZoneEnd).replaceAll("\"", "").trim();

                // Extract groundZone value
                int groundZoneStart = scriptContent.indexOf("var groundZone") + "var groundZone".length() + 3;
                int groundZoneEnd = scriptContent.indexOf(";", groundZoneStart);
                groundZone = scriptContent.substring(groundZoneStart, groundZoneEnd).replaceAll("\"", "").trim();
            }
        }

        // Print the extracted values
        List<String> zoneList=new ArrayList<>();
        zoneList.add(expressZone);
        zoneList.add(groundZone);
        log.info("偷区-接口查询成功"+zoneList);
        return  zoneList;
    }
}
